home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / unix / tail.1 < prev    next >
Internet Message Format  |  1988-12-06  |  17KB

  1. Path: xanth!ames!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i092:  tail - look at the end of a file
  5. Message-ID: <10496@swan.ulowell.edu>
  6. Date: 5 Dec 88 23:12:24 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 512
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: brant@uf.msc.umn.edu (Gary Brant)
  12. Posting-number: Volume 2, Issue 92
  13. Archive-name: unix/tail.1
  14.  
  15. Tail now works with *real* pipes, will run with the default stack size
  16. of 4000 bytes and has no line limit.
  17.  
  18. [uuencoded executable also enclosed; it's small.  ..Bob]
  19.  
  20. #    This is a shell archive.
  21. #    Remove everything above and including the cut line.
  22. #    Then run the rest of the file through sh.
  23. #----cut here-----cut here-----cut here-----cut here----#
  24. #!/bin/sh
  25. # shar:    Shell Archiver
  26. #    Run the following text with /bin/sh to create:
  27. #    readme
  28. #    tail.doc
  29. #    tail.uu
  30. #    tail.c
  31. #    alloc.c
  32. #    makefile
  33. # This archive created: Mon Dec  5 18:04:37 1988
  34. cat << \SHAR_EOF > readme
  35. This is a replacement for the tail which i submitted a few weeks ago.  It
  36. fixes a few problems, notably it now works with *real* pipes, it will run
  37. with the default stack size of 4000 bytes, and the arbitrary maximum line
  38. limit of 4096 has been removed all with no decrease in performance.
  39.  
  40.  
  41. -Gary Brant
  42.  
  43. The source & binary are freely distributable;  you may do anything
  44. you like with them except sell them for profit as long as you leave
  45. my name in the source and include this notice with the source files.
  46.  
  47. Have fun.
  48.  
  49.  
  50.          Gary Brant
  51.  
  52.     US mail: 1355 Eustis St. #1
  53.              St. Paul, MN 55108
  54.  
  55.     ARPA:     brant@uc.msc.umn.edu
  56. SHAR_EOF
  57. cat << \SHAR_EOF > tail.doc
  58. TAIL                USER COMMANDS            TAIL
  59.  
  60.  
  61.  
  62. NAME
  63.     tail - display the last part of a file
  64.  
  65. SYNOPSIS
  66.     tail +|-number [ filename ...]
  67.  
  68. DESCRIPTION
  69.     tail copies filename to the standard output beginning  at  a 
  70.     designated  place.   If no file is named, the standard input
  71.     is used.
  72.  
  73. OPTIONS
  74.     +number
  75.          Begin copying at number lines  from the beginning of the
  76.          file.  If number is not specified, the value 10 is used.
  77.  
  78.     -number
  79.          Begin copying at number lines  from the end of the file. 
  80.          If number is not specified, the value 10 is used.
  81.  
  82.  
  83. SEE ALSO
  84.     head
  85.  
  86. BUGS
  87.     Data for a tail relative to the end of the file  is stored in
  88.     a buffer, and thus is limited to  available memory.
  89. SHAR_EOF
  90. cat << \SHAR_EOF > tail.uu
  91.  
  92. begin 777 tail
  93. M```#\P`````````#``````````(```4N````E0````$```/I```%+D[Z"4!."
  94. M5?_R0FW_^C`L@`)(P"M`__12;?_Z,"W_^K!M``AL``$4,"W_^DC`Y8`@;0`*`
  95. M(G`(``P1`"UF)#`M__I(P.6`(&T`"B\P"`!.N@+(6$\K0/_T.6W_]H`"8```#
  96. MUC`M__I(P.6`(&T`"B)P"``,$0`K9B8P+?_Z2,#E@"!M``HO,`@`3KH"CEA/>
  97. M1(`K0/_T.6W_]H`"8```FE)L@`1(>@#","W_^DC`Y8`@;0`*+S`(`$ZZ!@I0H
  98. M3RM`__QF.$AL@&Q(>@"@3KH$DE!/2&R`;#`M__I(P.6`(&T`"B\P"`!.N@1XW
  99. M4$](;(!L/SP`"DZZ#'Q<3V!`+RW_]#`M__I(P.6`(&T`"B\P"``O+?_\86A/>
  100. M[P`,.T#_^"\M__Q.N@RR6$]*;?_X9PH_+?_X3KH#;E1/8`#^X$IL@`1F&B\MC
  101. M__1(>@`T2&R`0&$N3^\`##\`3KH#2E1/0F=.N@-"5$].74YU<@!T86EL.B!C-
  102. M86XG="!O<&5N(````$Y5_!)(YP\P*"T`$$J$;&`@!%*$2H!L'"\M``@_/`/H0
  103. M2&W\%DZZ`VA/[P`**T#\$F<"8-Q*K?P29S(O+0`,3KH!&%A/+RT`"#\\`^A(`
  104. M;?P63KH#/$_O``I*@&<02&R`5DAM_!9.N@-\4$]@V&```,J5RGX`+RT`"#\\D
  105. M`^A(;?P63KH##$_O``I*@&<``()(;?P63KH"Z%A/.T#__E*'OH1O#"P*)%(O-
  106. M!DZZ`=!83S`M__Y:0#\`3KH!/E1/*@!F*DAL@&Q(>@!V3KH#&%!/(`IG#BP*,
  107. M)%(O!DZZ`:!83V#N<!1,WPSP3EU.=2`*9@0D16`")H4F14AM_!8@15B(+PA.H
  108. MN@)J4$\@14*08`#_:"\M``QA1%A/(`IG'DAL@%8@2EB(+PA.N@*\4$\L"B12"
  109. M+P9.N@%(6$]@WG``8*9N;W0@96YO=6=H(&UE;6]R>2!F;W(@;&ES=`H`3E4`!
  110. M`$IL@`1G*DAL@%9(>@`H3KH"=E!/2&R`5B\M``A.N@)H4$](;(!62'H`$4ZZ"
  111. M`EI03TY=3G4]/3X@`"`\/3T*``!.50``2.<.`'@`>@%@,+P\`#!M'KP\`#EN6
  112. M&'(*(`1.N@G2*``0!DB`D'P`,$C`V(!@"C`L@`)(P"@`8`Q212!M``@<,%``I
  113. M9L8@!$S?`'!.74YU3E4``$Y=3G5.50``2.<(,#`M``C0?``/YDCG0'(`,@`H5
  114. M`29L@`8@"V820>R"!B9(*4B`!BE(@@9"K((*)%,@*@`$L(1E*B`J``2PA&8$]
  115. M)I)@#)FJ``35Z@`$)40`!"E+@`9"DB`*4(!,WPP03EU.=;7L@`9F#DZZ`((DA
  116. M0$J`9@1P`&#D)DHD4F"T8-Q.50``2.<`,"1M``A1BB9L@`:URV,$M=-E%+?3>
  117. M902URV(,M]-E!+73900F4V#D(&H`!-'*L=-F$"!3("@`!-&J``0@4R208`(D&
  118. MDR!K``31R['*9@P@*@`$T:L`!":28`(FBBE+@`9,WPP`3EU.=4Y5```O"D*GG
  119. M2'@0`$ZZ#\Q03R1`2H!F"'``)%].74YU0I(E?```$```!"!*4(@O"$ZZ_V!80
  120. M3R`L@`9@WDY5__Q(YP`P)&R`!B`*9R8F4BMJ``3__$JM__QC$$*J``0O+?_\A
  121. M+PI.N@^:4$\D2[7L@`9FUC\M``A.N@T:5$],WPP`3EU.=2!O``0@"")O``@0J
  122. MV6;\3G4@;P`$(`A*&&;\D<`@"%.`3G5.50``2.<(("1M``A3;0`,2FT`#&\@]
  123. M+RT`#DZZ`&XX`+!\__]83V<.($I2BA"$N'P`"F<"8-9"$KA\__]F$+7M``AFA
  124. M"G``3-\$$$Y=3G4@+0`(8/).50``+PHD;0`(2A)G)"\M``P@2E**$!!(@#\`_
  125. M3KH'LK!\__]<3V8(</\D7TY=3G5@V'``8/1.50``2.<(("1M``@O"DZZ`#(X>
  126. M`+!\__]83V<B,`1(P&`44Y((Z@`#``QP_TS?!!!.74YU8-9*@&?Z68!GY#`$%
  127. M8.I.50``+PHD;0`((%*QZ@`$90PO"F$66$\D7TY=3G4@4E*2$!!(@,!\`/]@B
  128. M[$Y5``!(YP@P)&T`"!`J``S`/``89PIP_TS?#!!.74YU"*H``@`,2JH`"&8(H
  129. M+PI.N@E`6$\0*@`,2(`(```'9S!![(!`)D@0*P`,2(#`?`"$L'P`A&8,/SS_K
  130. M_R\+3KH'^%Q/U_P````60>R!^+?(9=8_*@`0+RH`"!`J``U(@#\`3KH"/C@`<
  131. M2D!03VX42D1F!'`(8`)P$($J``QP_V``_WHP!$C`)*H`"-"J``@E0``$(%)2]
  132. MDA`02(#`?`#_8`#_6DY5```O"DZZ"'`D0$J`9@AP`"1?3EU.=2\*+RT`#"\M$
  133. M``AA!D_O``Q@Z$Y5``!(YP@@+RT`$$ZZ!MI![(`*)$A83TH29A`Y?``%@@YPE
  134. M`$S?!!!.74YU($HB;0`,$!BP&68$2@!F]I`A2(!G!%R*8-(_*@`$+RT`"$ZZ(
  135. M`$`X`+!\__]<3V8$<`!@Q"!M`!`11``-(&T`$!%\``$`#"`M`!!@K$Y5```_,
  136. M+0`,/SP#`2\M``AA!E!/3EU.=4Y5``!(YP\P)&T`"$ZZ"A(F;((0>`!@#C`$<
  137. MP?P`!DJS"`!G#E)$N&R!^&WL>@9@``#$""T``0`,9S!(>/__+PI.N@O^+`!0*
  138. M3V<@+P9.N@PV+PI.N@O$2H!03V8.3KH+SCH`L'P`S68``(Q(>`/M+PI.N@O<@
  139. M+`!*AE!/9F`(+0````QF!'H!8&Q(>`/N+PI.N@N^+`!03V8(3KH+DCH`8%1(B
  140. M>``A2'H`DDZZ#%XN`%!/9PHO!TZZ#`!83V`>2'@``4AZ`((O!DZZ"\A(>/__?
  141. M0J<O!DZZ"YY/[P`88"8P+0`,P'P%`+!\!0!F&"\&3KH+$GH$6$\Y18(.</],,
  142. MWPSP3EU.=3`$P?P`!B>&"``P!,'\``8@0-'+,6T`#``$""T``P`,9Q!(>``!2
  143. M0J<O!DZZ"T1/[P`,,`1@PF1O<RYL:6)R87)Y````3E4``$CG#"`X+0`(3KH(Y
  144. MS#`$P?P`!B1`U>R"$$I$;0JX;('X;`1*DF80.7P``H(.</],WP0P3EU.=3`J[
  145. M``3`?``#L'P``68*.7P`!8(.</]@X'``,"T`#B\`+RT`"B\23KH*O"H`L+S_M
  146. M____3^\`#&8,3KH*<CE`@@YP_V"T(`5@L&%P0^R"`D7L@@*UR68.,CP`%&L(>
  147. M=``BPE')__PI3X(4+'@`!"E.@AA(YX"`""X`!`$I9Q!+^@`(3J[_XF`&0J?SJ
  148. M7TYS0_H`($ZN_F@I0((<9@PN/``#@`=.KO^48`1.N@`:4$].=61O<RYL:6)R@
  149. M87)Y`$GY``!__DYU3E4``"\*2'D``0``,"R!^,'\``8O`$ZZ"FPI0((04$]FQ
  150. M%$*G2'D``0``3KH*,%!/+FR"%$YU(&R"$$)H``0@;((0,7P``0`0(&R"$#%\&
  151. M``$`"B!L@A0@+((4D*@`!%"`*4""("!L@B`@O$U!3EA"ITZZ"B`D0$JJ`*Q8;
  152. M3V<N+RT`#"\M``@O"DZZ`*XY?``!@B0@;((0`&B````$(&R"$`!H@```"D_O3
  153. M``Q@0DAJ`%Q.N@H^2&H`7$ZZ"@`I0((F(&R")DJH`"103V<0(&R")B)H`"0ON
  154. M$4ZZ"/)83R\L@B8O"DZZ^,@I;((F@BI03TZZ"/(@;((0((!.N@D@(&R"$"%`V
  155. M``9G%DAX`^U(>@`J3KH(_"!L@A`A0``,4$\O+((J/RR"+DZZ]2)"9TZZ!PQ0J
  156. M3R1?3EU.=2H`3E4``$CG##`D;0`0(&T`"$JH`*QG&"!M``@@*`"LY8`H`"!$%
  157. M("@`$.6`)D!@!"9L@?H0$TB`2,#0K0`,5(`Y0((P0J<P+((P2,`O`$ZZ"/XIT
  158. M0((R4$]F"$S?##!.74YU$!-(@#H`/P4@2U*(+P@O+((R3KH!?C`%2,`@0-'LK
  159. M@C)#^@%$$-EF_#\M``XO"B\L@C).N@$Z(&R",D(P4``Y?``!@BXP!4C`T*R"I
  160. M,B9`4HLD2T_O`!00$TB`.@"P?``@9QBZ?``)9Q*Z?``,9PRZ?``-9P:Z?``*#
  161. M9@12BV#8#!,`(&UZ#!,`(F8N4HL@2U*+$!!(@#H`9QX@2E**$(6Z?``B9A`,[
  162. M$P`B9@12BV`&0BK__V`"8-9@."!+4HL0$$B`.@!G)KI\`"!G(+I\``EG&KI\&
  163. M``QG%+I\``UG#KI\``IG""!*4HH0A6#.($I2BD(02D5F`E.+4FR"+F``_UI"-
  164. M$D*G,"R"+E)`2,#E@"\`3KH'W"E`@BI03V8(0FR"+F``_MAZ`"9L@C)@)#`%/
  165. M2,#E@"!L@BHABP@`($L@"$H89OR1P%.(,`A20$C`U\!21;IL@BYMUC`%2,#E7
  166. M@"!L@BI"L`@`8`#^E"``,#Q__V`$,"\`#"!O``1*&&;\4T@B;P`(4T`0V5?(C
  167. M__QG`D(0("\`!$YU3.\#```$(`@R+P`,8`(0V5?)__QG!E)!8`)"&%')__Q.H
  168. M=4CG<``T`<3`)@%(0\;`2$-"0]2#2$#`P4A`0D#0@DS?``Y.=4Y5```O!#@M(
  169. M``@O+0`*/P1.N@`PN'P`"EQ/9B0@;0`*$"@`#$B`"```!V<4/SS__R\M``I.V
  170. MN@#T7$\H'TY=3G5@^$Y5```O"B1M``H@4K'J``1E&#`M``C`?`#_/P`O"DZZ+
  171. M`,A<3R1?3EU.=2!24I(0+0`)$(!(@,!\`/]@Z$Y5```O"D'L@$`D2"!*U?P`+
  172. M```6+PAA$%A/0>R!^+7(9>HD7TY=3G5.50``2.<(("1M``AX`"`*9@IP_TS?'
  173. M!!!.74YU2BH`#&=0""H``@`,9PP_//__+PIA4C@`7$\0*@`-2(`_`$ZZ!1R(S
  174. M0`@J``$`#%1/9PHO*@`(3KH"+EA/""H`!0`,9Q(O*@`23KH"P"\J`!).N@(4-
  175. M4$]"DD*J``1"J@`(0BH`##`$8)!.5?_^2.<(("1M``A!^O]&*4B"-@@J``0`B
  176. M#&<*</],WP003EU.=0@J``(`#&<P(%*1Z@`(.`@_!"\J``@0*@`-2(`_`$ZZ?
  177. M`H"P1%!/9Q`(Z@`$``Q"DD*J``1P_V#`#&W__P`,9A`(J@`"``Q"DD*J``1P.
  178. M`&"H2JH`"&8(+PI.N@":6$\,:@`!`!!F*AMM``W__S\\``%(;?__$"H`#4B`<
  179. M/P!.N@(BL'P``5!/9J`P+0`,8`#_:B2J``@P*@`02,#0J@`()4``!`CJ``(`6
  180. M#"!24I(0+0`-$(!(@,!\`/]@`/\^3E4``"\*0>R`0"1(2BH`#&<8U?P````6W
  181. M0>R!^+7(90AP`"1?3EU.=6#B0I)"J@`$0JH`""`*8.I.5?_\+PHD;0`(/SP$.
  182. M`$ZZ`,`K0/_\5$]F\``$`$"!*T?P````.)4@`""1?3EU.=35\!```$`CJS
  183. M``$`#"5M__P`"!`J``U(@#\`3KH`XDI`5$]G!@`J`(``#&#.3E4``$CG`#`D^
  184. M;(("8!0F4B`J``10@"\`+PI.N@1\4$\D2R`*9NA"K(("3-\,`$Y=3G5.50``J
  185. M+PI!^O_&*4B".D*G("T`"%"`+P!.N@0F)$!*@%!/9@AP`"1?3EU.=22L@@(EJ
  186. M;0`(``0I2H("(`I0@&#F3E4``'``,"T`""\`8;)83TY=3G5.50``2.<`,)?+C
  187. M)&R"`F`.(&T`"%&(L<IG$B9*)%(@"F;N</],WPP`3EU.=2`+9P0FDF`$*5*"+
  188. M`B`J``10@"\`+PI.N@/.<`!03V#83E4``"\*,"T`",'\``8D0-7L@A!*;0`(B
  189. M;0XP+0`(L&R!^&P$2I)F#CE\``*"#G#_)%].74YU,"T`",'\``8@;((0+S`()
  190. M`$ZZ`L9*@%A/9P1P`6`"<`!@V$Y5```O+0`(3KH"D$J`6$]F#DZZ`IHY0((.:
  191. M</].74YU<`!@^$Y5``!(YPP@."T`"$ZZ`'`P!,'\``8D0-7L@A!*1&T*N&R!@
  192. M^&P$2I)F$#E\``*"#G#_3-\$,$Y=3G4P*@`$P'P``V8*.7P`!8(.</]@Y'``W
  193. M,"T`#B\`+RT`"B\23KH"D"H`L+S_____3^\`#&8,3KH"&CE`@@YP_V"X(`5@B
  194. MM$Y5__Q(>!``0J=.N@+X*T#__`@```Q03V<22FR")&8(("W__$Y=3G5.N@`&M
  195. M<`!@]$Y5``!(>``$2'H`'$ZZ`?XO`$ZZ`BP_/``!3KH`#D_O``Y.74YU7D,*L
  196. M`$Y5``!*K((V9P8@;((V3I`_+0`(3KH`"%1/3EU.=4Y5__PO!#`M``A(P"M`>
  197. M__Q*K((09RAX`&`*/P1.N@#^5$]21+AL@?AM\#`L@?C!_``&+P`O+((03KH"N
  198. M&E!/2JR".F<&(&R".DZ02JR!_F<*+RR!_DZZ`9)83TJL@CYG""!L@CX@K()"!
  199. M2JR"1F<*+RR"1DZZ`:I83TJL@DIG"B\L@DI.N@&:6$]*K().9PHO+().3KH![
  200. MBEA/2JR"4F<*+RR"4DZZ`7I83RQX``0(+@`$`2EG%"\-2_H`"DZN_^(J7V`&C
  201. M0J?S7TYS2JR")F8P2JR",F<H,"R",$C`+P`O+((R3KH!<C`L@BY20$C`Y8`OR
  202. M`"\L@BI.N@%>3^\`$&`.3KH!2"\L@B9.N@%X6$\@+?_\+FR"%$YU*!].74YU6
  203. M3E4``$CG#B`X+0`(,`3!_``&)$#5[((02D1M"KAL@?AL!$J29A`Y?``"@@YPV
  204. M_TS?!'!.74YU""H`!P`$9@@O$DZZ``I83T*2<`!@XB(O``0L;((<3N[_W"(OJ
  205. M``0L;((<3N[_@B(O``0L;((<3N[_N"QL@AQ.[O_*+&R"'$[N_WPB+P`$+&R",
  206. M'$[N_RA,[P`&``0L;((<3N[_K$SO``8`!"QL@AQ.[O_B+&R"'$[N_\1,[P`.W
  207. M``0L;((<3N[_UDSO``X`!"QL@AQ.[O^^3OH``B(O``0L;((<3N[_IDSO``X`&
  208. M!"QL@AQ.[O_02.<!!$SO((``#"QL@AA.KO^43-\@@$YU(F\`!"QL@AA.[OYB2
  209. M3OH``DSO``,`!"QL@AA.[O\Z(F\`!"QL@AA.[O[:+&R"&$[N_WQ.^@`"(F\`2
  210. M!"`O``@L;((83N[_+B!O``0L;((83N[^C"QL@A@B;P`$("\`"$[N_=@B;P`$%
  211. M+&R"&$[N_H9,[P`#``0L;((83N[^SB!O``0L;((83N[^@````^P````!````=
  212. M`0``";8````````#\@```^H```"```H```````!R``````!R*P````)W````T
  213. M`P%W*P```P)A````"0%A*P``"0)X````!0%X*P``!0(`````````````````5
  214. M```````!``````$``````````````````````0$````!````````````````%
  215. M``````$"`````0``````````````````````````````````````````````$
  216. M`````````````````````````````````````````````````````````````
  217. M`````````````````````````````````````````````````````````````
  218. M`````````````````````````````````````````````````````````````
  219. M`````````````````````````````````````````````````````````````
  220. M`````````````````````````````````````````````````````````````
  221. M`````````````````````````````````````````````````````````````
  222. M`````````````````````````````````````````````````````````````
  223. M```````````````````````````````````````4``````````````/R```#,
  224. )ZP````$```/RA
  225. ``
  226. end
  227. size 5904
  228. SHAR_EOF
  229. cat << \SHAR_EOF > tail.c
  230. /* tail.c - print the last few lines in a file.  If count is specified, *
  231.  *    that many lines are printed instead of the default value of    *
  232.  *    ten lines.  If no files are specified, head reads standard    *
  233.  *    input.                                *
  234.  *                                    *
  235.  * tail [-<count>] [<file> ...]                     *
  236.  *                                    *
  237.  * tail (C) 1988 by Gary L. Brant                    *
  238.  *                                    *
  239.  * :ts=8                                */
  240.  
  241. #include <stdio.h>
  242. #define   MAXLINE   1000
  243.  
  244. void fputs ();
  245. int default_lines = 10; /* default number of lines to list */
  246. int headlin = 0;
  247.  
  248. typedef struct list {
  249.    struct list *nxt;
  250.    char line[MAXLINE];
  251. };
  252.  
  253.  
  254. main (argc, argv)    /* list 1st n lines of a file */
  255. int  argc;
  256. char *argv[];
  257. {
  258.    FILE *input, *fopen ();
  259.    void fclose ();
  260.    int i = 0, rval;
  261.    long maxlines, convert ();
  262.    char ch;
  263.  
  264.    maxlines = default_lines;
  265.    while (++i < argc) {
  266.       if (argv [i][0] == '-') {     /* process line count argument */
  267.      maxlines = convert (argv[i]);
  268.      default_lines = maxlines;
  269.       } else if (argv [i][0] == '+') {
  270.      maxlines = -convert (argv[i]);
  271.      default_lines = maxlines;
  272.       } else {
  273.      ++headlin;
  274.      if ((input = fopen (argv[i], "r")) == NULL) {
  275.         fputs ("tail: can't open ", stderr);
  276.         fputs (argv[i], stderr);
  277.         putc ('\n', stderr);
  278.         break;
  279.      } else {
  280.         rval = list (input, argv[i], maxlines);
  281.         fclose (input);
  282.         if (rval)
  283.                quit (rval);
  284.      }
  285.       }
  286.    }
  287.    if (!headlin)
  288.       quit (list (stdin, "", maxlines));
  289.    quit (0);
  290. }
  291.  
  292.  
  293. list (fp, fn, maxlines)     /* list tail of a file */
  294. FILE *fp;
  295. char *fn;
  296. register long maxlines;
  297. {
  298.    int n;
  299.    char line[MAXLINE];
  300.    char *c, *fgets (), *alloc ();
  301.  
  302.    if (maxlines < 0) {        /* +n, head relative list */
  303.       while (maxlines++ < 0 && (c = fgets (line, MAXLINE, fp)) != NULL);
  304.       if (c != NULL) {
  305.      heading (fn);
  306.      while ((fgets (line, MAXLINE, fp)) != NULL)
  307.         fputs (line, stdout);
  308.       }
  309.    } else {            /* -n, tail relative list */
  310.       register struct list *head = NULL, *curr, *next, *p;
  311.       register long nlin = 0;
  312.  
  313.       while ((fgets (line, MAXLINE, fp)) != NULL) {
  314.          n = strlen (line);
  315.      if (++nlin > maxlines) {    /* de-link 1st line */
  316.         p = head;
  317.         head = head->nxt;
  318.         freeit (p);
  319.      }
  320.      if ((next = (struct list *) alloc (n+5)) == NULL) {
  321.         fputs ("not enough memory for list\n", stderr);
  322.         while (head != NULL) {
  323.            p = head;
  324.            head = head->nxt;
  325.            freeit (p);
  326.         }
  327.         return (20);
  328.      }
  329.      if (head == NULL)
  330.         head = next;
  331.      else
  332.         curr->nxt = next;
  333.      curr = next;
  334.      strcpy (next->line, line);
  335.      next->nxt = NULL;
  336.       }
  337.       heading (fn);
  338.  
  339.       /* now print the lines in the list, deallocating as we go */
  340.  
  341.       while (head != NULL) {
  342.          fputs (head->line, stdout);
  343.      p = head;
  344.      head = head->nxt;
  345.      freeit (p);
  346.       }
  347.    }
  348.    return (0);
  349. }
  350.  
  351.  
  352. heading (filename)
  353. char *filename;
  354. {
  355.    if (headlin) {
  356.       fputs ("==> ", stdout);
  357.       fputs (filename, stdout);
  358.       fputs (" <==\n", stdout);
  359.    }
  360. }
  361.  
  362.  
  363. long convert (string)
  364. char string[];
  365. {
  366.    register long maxlines = 0;
  367.    register int j;
  368.    register char ch;
  369.  
  370.    for (j = 1; (ch = string[j]) != '\0'; j++)
  371.    if (ch >= '0' && ch <= '9') {
  372.       maxlines *= 10;
  373.       maxlines += ch - '0';
  374.    } else {
  375.       maxlines = default_lines;
  376.       break;
  377.    }
  378.    return (maxlines);
  379. }
  380.  
  381.  
  382. void _wb_parse ()
  383. {
  384. }
  385. SHAR_EOF
  386. cat << \SHAR_EOF > alloc.c
  387. /* alloc.c - memory allocator
  388.  *
  389.  * The point of this is that it is about 4 times faster than MANX malloc/free
  390.  * in c.lib.  Malloc in heapmem.o will not allocate a second heap if the first
  391.  * is exhausted.
  392.  * :ts=8
  393.  */
  394.  
  395.  
  396. #define NULL        0L
  397. #define HOWMUCH        4096L    /* how much memory to AllocMem() at a time */
  398.  
  399. typedef struct header {
  400.       struct header *next;    /* next block */
  401.       unsigned long size;    /* block size */
  402. };
  403.  
  404. struct header first;
  405.  
  406. struct header *head = NULL;    /* start of list */
  407.  
  408.  
  409. char *alloc (bytes)
  410. unsigned bytes;
  411. {
  412.    struct header *getmem ();
  413.    register struct header *p, *q;
  414.    register long size;
  415.  
  416.    size = (((bytes + 2 * sizeof (struct header) - 1) >> 3) << 3);
  417.    if ((q = head) == NULL) {
  418.       first.next = head = q = &first;
  419.       first.size = 0L;
  420.    }
  421.    for (p = q->next; ; q = p, p = p->next) {
  422.       if (p->size >= size) {    /* if this block is large enough */
  423.          if (p->size == size)
  424.         q ->next = p->next;
  425.      else {        /* remove memory from tail of block */
  426.         p->size -= size;
  427.         p = (struct header *) ((char *) p + p->size);
  428.            p->size = size;
  429.      }
  430.      head = q;
  431.      p->next = NULL;
  432.      return ((char *) (p+1));
  433.       }
  434.       if (p == head)    /* back where we started */
  435.      if ((p = getmem ()) == NULL)
  436.         return (NULL);    /* cannot allocate memory */
  437.    }
  438. }
  439.  
  440.  
  441. /* freeit - put block back in free list */
  442.  
  443. freeit (ptr)
  444. char *ptr;
  445. {
  446.    register struct header *p, *q;
  447.  
  448.    p = (struct header *) ptr - 1;
  449.    for (q = head; ; q = q->next) {
  450.       if (p > q && p < q->next)
  451.      break;        /* new block goes between q & q->next */
  452.       if (q >= q->next && p > q)
  453.      break;        /* new block goes at end of list */
  454.       if (q >= q->next && p < q->next)
  455.      break;        /* new block goes at beginning of list */
  456.    }
  457.  
  458.    if ((struct header *) ((char *) p + p->size) == q->next) {
  459.       p->size += q->next->size;
  460.       p->next = q->next->next;
  461.    } else {
  462.       p->next = q->next;
  463.    }
  464.    if ((struct header *) ((char *) q + q->size) == p) {
  465.       q->size += p->size;
  466.       q->next = p->next;
  467.    } else {
  468.       q->next = p;
  469.    }
  470.    head = q;
  471. }
  472.  
  473.  
  474. /* getmem - request more memory from system */
  475.  
  476. struct header *getmem ()
  477. {
  478.    char *AllocMem ();
  479.    register struct header *up;
  480.  
  481.    if ((up = (struct header *) AllocMem (HOWMUCH, 0L)) == NULL)
  482.       return (NULL);    /* can't get more memory */
  483.    up->next = NULL;
  484.    up->size = HOWMUCH;
  485.    freeit ((char *) (up + 1));
  486.    return (head);
  487. }
  488.  
  489.  
  490. quit (code)
  491. int code;
  492. {
  493.    register struct header *p, *q;
  494.    unsigned long size;
  495.  
  496.    p = head;
  497.    do {
  498.       if (p == NULL)
  499.          break;
  500.       q = p->next;
  501.       if ((size = p->size) > 0L) {
  502.      p->size = 0L;
  503.          FreeMem (p, size);
  504.       }
  505.       p = q;
  506.    } while (p != head);
  507.    exit (code);
  508. }
  509. SHAR_EOF
  510. cat << \SHAR_EOF > makefile
  511. CFLAGS=-s
  512.  
  513.  
  514. tail:    tail.o alloc.o
  515.     ln tail.o alloc.o -lc
  516.  
  517. SHAR_EOF
  518. #    End of shell archive
  519. exit 0
  520. -- 
  521. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  522. Have five nice days.
  523.